﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using NUS.ISS.ARS.Common;
using NUS.ISS.ARS.BusinessEntity;
using NUS.ISS.ARS.BusinessEntity.ViewModels;
using NUS.ISS.ARS.BusinessFacade.Interface;
using NUS.ISS.ARS.BusinessFacade;
using Microsoft.Practices.Unity;
using NUS.ISS.ARS.Web.Helper;

namespace NUS.ISS.ARS.Web.PageController
{
    public class BookingBaseController:Page
    {
        #region "Constructor, Class Variables & Properties"
        private string _currentPage;
        protected string CurrentPage
        {
            get { return _currentPage; }
            set { _currentPage = value; }
        }
        private IBookingBF _bookingBF;
        private IAdminBF _adminBF;
        private IUnityContainer _myContainer = null;        
        protected ReservationViewObject ReservationData
        {
            get 
            {
                if (Session[Constants.BOOKING_SESSION_KEY] == null)
                {
                    ReservationData = new ReservationViewObject();
                }
                return Session[Constants.BOOKING_SESSION_KEY] as ReservationViewObject;
            }
            private set { Session[Constants.BOOKING_SESSION_KEY] = value; }
        }              
        protected IEnumerable<FlightBookingTripView> FlightBookingTrips
        {
            get { 
                 if(Session[Constants.BOOKING_TRIPS_SESSION_KEY] == null)
                 {
                     FlightBookingTrips = new List<FlightBookingTripView>();
                 }
                 return Session[Constants.BOOKING_TRIPS_SESSION_KEY] as IEnumerable<FlightBookingTripView>;
            }
            private set { Session[Constants.BOOKING_TRIPS_SESSION_KEY] = value; }
        }
        protected IEnumerable<FlightBookingTripView> OtherFlightBookingTrips
        {
            get
            {//Remove the currently booked flights
                return FlightBookingTrips.Where(t => t.ToBeChanged != true);
            }
        }
        
        protected string BookingReferenceNumber {
            get
            {
                if (Session[Constants.BOOKING_REFERENCE_KEY] == null)
                {
                    BookingReferenceNumber = string.Empty;
                }
                return Session[Constants.BOOKING_REFERENCE_KEY].ToString(); 
            }
            private set { Session[Constants.BOOKING_REFERENCE_KEY] = value; }
        }
        public bool IsManageBooking 
        {
            get
            {
                return !String.IsNullOrEmpty(BookingReferenceNumber);
            }
        }
        private Dictionary<string, string> _nevigator;

        protected bool IsPrePageVisible { get; set; }
        protected bool IsNextPageVisible { get; set; }
        protected void Page_Load(object sender, EventArgs e)
        {
            Object retrievedContainer = Application[Constants.UNITY_CONTAINER];
            _myContainer = retrievedContainer as IUnityContainer;
            _bookingBF = _myContainer.Resolve<IBookingBF>();
            _adminBF = _myContainer.Resolve<IAdminBF>();
            _nevigator = GetNevigation();
            SetPreAndNextPageButtonVisibility();
        }
        #endregion

        private void SetPreAndNextPageButtonVisibility()
        {
            IsPrePageVisible = true;
            IsNextPageVisible = true;

            if(_nevigator!=null && !String.IsNullOrEmpty(CurrentPage))
            {
                //First Page
                if(_nevigator.FirstOrDefault().Key.Equals(CurrentPage))
                {
                    IsPrePageVisible = false;
                }
                //Last Page
                else if (_nevigator.LastOrDefault().Value.Equals(CurrentPage))
                {
                    IsNextPageVisible = false;
                }
            }
        }

        #region "Class Variables & Properties"
        private Dictionary<string, string> GetNevigation()
        {
            _nevigator = new Dictionary<string, string>();

            if (IsManageBooking)
            {
                _nevigator.Add("SearchBookings.aspx", "MyBookings.aspx");
                _nevigator.Add("MyBookings.aspx", "SearchFlight.aspx");
                _nevigator.Add("SearchFlight.aspx", "SelectFlight.aspx");
                _nevigator.Add("SelectFlight.aspx", "Summary.aspx");
                _nevigator.Add("Summary.aspx", "CheckOut.aspx");               
            }
            else
            {
                _nevigator.Add("SearchBookings.aspx", "MyBookings.aspx"); //if not found
                _nevigator.Add("MyBookings.aspx", "SearchFlight.aspx");
                _nevigator.Add("SearchFlight.aspx", "SelectFlight.aspx");
                _nevigator.Add("SelectFlight.aspx", "PassengerInfo.aspx");
                _nevigator.Add("PassengerInfo.aspx", "Summary.aspx");
                _nevigator.Add("Summary.aspx", "ContractInfo.aspx");
                _nevigator.Add("ContractInfo.aspx", "CheckOut.aspx");
            }

            return _nevigator;
        }

        protected void MoveToNextPage()
        {
            Response.Redirect(_nevigator[_currentPage]);
        }

        protected void MoveToPrePage()
        {
            string prePageURL= "";
            foreach(var prePage in _nevigator)
            {
                if(prePage.Value.Equals(_currentPage))
                {
                    prePageURL = prePage.Key;
                    break;
                }
            }

            Response.Redirect(prePageURL);
        }
        
        #endregion

        protected List<FlightSchedule> GetAllFilghts()
        {
            return _adminBF.GetAllFlightSchedules().ToList();
        }

        protected IEnumerable<City> GetAllFlightCities()
        {
            return _bookingBF.GetAllFlightCities();
        }

        protected void SearchFlights(ReservationViewObject rvData)
        {
            ReservationData = rvData;
            var trips = _bookingBF.SearchFlights(ReservationData); 

            if (IsManageBooking)
            {
                //remove the currently booked trips from the list
                foreach (var tripToBeChanged in FlightBookingTrips)
                {                    
                    trips = trips.Where(t => !(t.FlightDate == tripToBeChanged.FlightDate && t.FlightScheduleId == tripToBeChanged.FlightScheduleId)).ToList();
                }
                
            }
            //remove prev search except alry booked ones, then union with current search & save in session
            FlightBookingTrips = FlightBookingTrips.Where(t => t.ToBeChanged == true).Union(trips); 
        }

        protected void UpdateSelectedTrips(IEnumerable<FlightBookingTripView> trips)
        {
            if (IsManageBooking)
            {
                //get the trips to be changed
                var tripsToBeChanged = FlightBookingTrips.Where(t => t.ToBeChanged == true);
                FlightBookingTrips = tripsToBeChanged.Union(trips); //union with new trips selected
            }
            else
            {
                ReservationData.SelectedBookingTrips = trips.ToList();
            }
        }

        protected PriceSummaryView GetPriceSummary()
        {
            PriceSummaryView ps;
            if (IsManageBooking)
            {
                ps = _bookingBF.GetPriceSummary(FlightBookingTrips, IsManageBooking);
            }
            else
            {
                ps = _bookingBF.GetPriceSummary(ReservationData.SelectedBookingTrips, IsManageBooking);
            }
            ReservationData.TotalDue = ps.TotalDue;
            ps.isIncludeChild = ReservationData.NumOfChild > 0;

            return ps;
        }

       
        #region "Manage Booking Related"

        protected void SearchBookings(string refNo, string firstName, string lastName)
        {
            FlightBookingTrips = _bookingBF.GetFlightBookingsByRefNoAndName(refNo, firstName, lastName);
            if (FlightBookingTrips.Count() > 0)
            {
                BookingReferenceNumber = FlightBookingTrips.FirstOrDefault().ReferenceNumber;
                _nevigator = GetNevigation();
            } 
        }        

        protected void MarkToChangeBookingTrip(List<long> tripIds)
        {
            foreach (FlightBookingTripView trip in FlightBookingTrips)
            {
                foreach(var tripId in tripIds)
                {
                    if (trip.FlightBookingTripId == tripId)
                    {
                        trip.ToBeChanged = true;
                    }
                }
            }
            //remove unmarked items from session
            FlightBookingTrips = FlightBookingTrips.Where(t => t.ToBeChanged == true);

            if (FlightBookingTrips.Count() == 0)
            {
                BookingReferenceNumber = string.Empty; //no longer a manage booking
                _nevigator = GetNevigation();
            }
        }

        protected List<int> GetNumOfPassengersArrayByBookingRefNo()
        {
            return _bookingBF.GetNumOfPassengersArrayByBookingRefNo(BookingReferenceNumber);
        }

        protected SaveResult SaveChangedBookings()
        {
            return _bookingBF.SaveChangedBookings(FlightBookingTrips);
        }

        protected ICollection<Country> GetAllCountries()
        {
            if (CacheHelper.Get<List<Country>>(Constants.COUNTRY_CACHE_KEY) == null)
            {
                Cache.Insert(Constants.COUNTRY_CACHE_KEY, _adminBF.GetAllCountries());
            }
            return CacheHelper.Get<List<Country>>(Constants.COUNTRY_CACHE_KEY);
        }

        protected SaveResult SaveSessionToDatabase()
        {
           return _bookingBF.CreateBookings(ReservationData);
        }

        protected void ClearSessions()
        {           
            Session[Constants.BOOKING_SESSION_KEY] = null;
            Session[Constants.BOOKING_TRIPS_SESSION_KEY] = null;
            Session[Constants.SELECTED_BOOKING_TRIPS_SESSION_KEY] = null;
        }

        #endregion

    }
}